/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package PackageUpdater.UI;

import Manager.DownloaderManager;
import PackageUpdater.Config.SysConfig;
import PackageUpdater.Config.UpdateFileEntry;
import PackageUpdater.Config.UpdateList;
import PackageUpdater.Update.IUpdateTaskProgressEvent;
import PackageUpdater.Update.JUpdateManager;
import java.awt.Font;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

/**
 *
 * @author wcss
 */
public class UpdateUI extends javax.swing.JFrame implements IUpdateTaskProgressEvent, Runnable {

    private ArrayList<UpdateList> needUpdateList = new ArrayList<UpdateList>();
    public static String currentLanguage = "english";

    public static String getLangTxt(String code) {
        return LanguageArrays.getLanguageText(currentLanguage, code);
    }
    public static String runMode = "min";
    public static Queue<UpdateList> updateQueues = new LinkedList<UpdateList>();
    private static Boolean ableStartupDownload = false;
    private static UpdateList currentUpdateObj = null;
    private static int currentUpdateIndex = 0;

    /**
     * Creates new form UpdateUI
     */
    public UpdateUI() {
        initComponents();
        this.loadConfig();
    }

    private String getDesktopDir() {
        File dirConfig = new File(JAppToolKit.JRunHelper.getUserHomeDirPath() + "/.config/user-dirs.dirs");
        if (dirConfig.exists()) {
            try {
                String result = "";
                String[] teams = JAppToolKit.JDataHelper.readAllLines(dirConfig.getAbsolutePath());
                for (String s : teams) {
                    if (s.startsWith("XDG_DESKTOP_DIR=")) {
                        result = s.replace("\"", "").replace("'", "").replace("XDG_DESKTOP_DIR=", "").replace("$HOME/", JAppToolKit.JRunHelper.getUserHomeDirPath() + "/");
                        break;
                    }
                }
                return result.trim();
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        } else {
            return "";
        }
    }

    private void printLogs(String txts) {
        this.txtContent.setText(this.txtContent.getText() + txts + "\n");
    }

    private void clearLogs() {
        this.txtContent.setText("");
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        txtContent = new javax.swing.JTextArea();
        progress = new javax.swing.JProgressBar();
        btnStartup = new javax.swing.JButton();
        btnExit = new javax.swing.JButton();
        lblState = new javax.swing.JLabel();
        btnUpdate = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setResizable(false);

        txtContent.setColumns(20);
        txtContent.setFont(new java.awt.Font("文泉驿微米黑", 0, 12)); // NOI18N
        txtContent.setRows(5);
        jScrollPane1.setViewportView(txtContent);

        btnStartup.setFont(new java.awt.Font("文泉驿微米黑", 1, 12)); // NOI18N
        btnStartup.setText("启动");
        btnStartup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnStartupActionPerformed(evt);
            }
        });

        btnExit.setFont(new java.awt.Font("文泉驿微米黑", 1, 12)); // NOI18N
        btnExit.setText("退出");
        btnExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnExitActionPerformed(evt);
            }
        });

        lblState.setFont(new java.awt.Font("文泉驿微米黑", 1, 12)); // NOI18N
        lblState.setText(" jLabel1");

        btnUpdate.setFont(new java.awt.Font("文泉驿微米黑", 1, 12)); // NOI18N
        btnUpdate.setText("启动");
        btnUpdate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnUpdateActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 671, Short.MAX_VALUE)
            .addComponent(progress, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(btnStartup, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(8, 8, 8)
                .addComponent(btnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(lblState, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 344, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblState, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(progress, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(btnUpdate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnStartup, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed
        // TODO add your handling code here:
        int option = JOptionPane.showConfirmDialog(null, getLangTxt("011"), "", JOptionPane.YES_NO_OPTION);
        if (option == JOptionPane.YES_OPTION) {
            System.exit(0);
        }
    }//GEN-LAST:event_btnExitActionPerformed

    private void btnStartupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartupActionPerformed
        // TODO add your handling code here:
        String appPath = JUpdateManager.manager.getConfigObj().getSoftwareWorkspace() + "/" + JUpdateManager.manager.getConfigObj().getAppStartupScript();
        if (new File(appPath).exists()) {
            try {
                JAppToolKit.JRunHelper.runSysCmd(appPath, false);
                this.dispose();
            } catch (Exception ex) {
                Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_btnStartupActionPerformed

    private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnUpdateActionPerformed
        // TODO add your handling code here:
        btnUpdate.setEnabled(false);
        int[] team = new int[needUpdateList.size()];
        int indexx = 0;
        for (UpdateList ul : needUpdateList) {
            team[indexx] = ul.getUpdateIndex();
            indexx++;
        }
        Arrays.sort(team);
        updateQueues.clear();

        for (int ii : team) {
            for (UpdateList ull : needUpdateList) {
                if (ull.getUpdateIndex() == ii) {
                    updateQueues.offer(ull);
                    break;
                }
            }
        }

        currentUpdateIndex = 0;
        ableStartupDownload = true;
        Thread TT = new Thread(this);
        TT.setDaemon(true);
        TT.start();
    }//GEN-LAST:event_btnUpdateActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        final String[] param = args;

        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if (javax.swing.UIManager.getCrossPlatformLookAndFeelClassName().equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(UpdateUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(UpdateUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(UpdateUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(UpdateUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        Font f = new Font("文泉驿微米黑", Font.PLAIN, 12);
        UIManager.put("OptionPane.messageFont", f);
        UIManager.put("OptionPane.buttonFont", f);

        //</editor-fold>

        if (args.length >= 2) {
            if (args[0] != null && (args[0].equals("english") || args[0].equals("chinese"))) {
                currentLanguage = args[0];
            } else {
                currentLanguage = "english";
            }

            if (args[1] != null && new File(args[1]).exists()) {
                JUpdateManager.manager.setConfigPath(args[1]);
                /* Create and display the form */
                java.awt.EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        new UpdateUI().setVisible(true);
                    }
                });
            } else {
                javax.swing.JOptionPane.showMessageDialog(null, getLangTxt("001"));
                System.exit(0);
            }
        } else {
            javax.swing.JOptionPane.showMessageDialog(null, getLangTxt("001"));
            System.exit(0);
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnExit;
    private javax.swing.JButton btnStartup;
    private javax.swing.JButton btnUpdate;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblState;
    private javax.swing.JProgressBar progress;
    private javax.swing.JTextArea txtContent;
    // End of variables declaration//GEN-END:variables

    private void showUpdateInfo(int curIndex, Boolean isInstallInfo) {
        if (isInstallInfo) {
            lblState.setText(getLangTxt("009").replace("{T}", needUpdateList.size() + "").replace("{I}", curIndex + ""));
        } else {
            lblState.setText(getLangTxt("008").replace("{T}", needUpdateList.size() + "").replace("{I}", curIndex + ""));
        }
    }

    @Override
    public void handleUpdateList(JUpdateManager sender, String name) {
        try {
            clearLogs();
            needUpdateList.clear();
            UpdateList[] team = JUpdateManager.manager.checkNeedUpdateEntrys();
            needUpdateList.addAll(Arrays.asList(team));
            String[] logs = JAppToolKit.JDataHelper.readAllLines(JUpdateManager.manager.logTextFile);
            printLogs(getLangTxt("005") + JUpdateManager.manager.getConfigObj().getHomepage());
            printLogs(getLangTxt("006") + JUpdateManager.manager.getConfigObj().getMaintainer());
            printLogs(getLangTxt("007"));
            for (String s : logs) {
                printLogs(s);
            }
            if (needUpdateList.size() > 0) {
                showUpdateInfo(0, false);
                btnUpdate.setEnabled(true);
            } else {
                //showUpdateInfo(0, false);
                lblState.setText(getLangTxt("014"));
                btnUpdate.setVisible(false);
                btnStartup.setVisible(true);
            }
        } catch (Exception ex) {
            Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void handleUpdateError(JUpdateManager sender, String name, String error) {
        javax.swing.JOptionPane.showMessageDialog(null, getLangTxt("001"));
        System.exit(0);
    }

    @Override
    public void handleUpdateFiles(JUpdateManager sender, String name) {
        int indexx = Integer.parseInt(name.replace("%UFile", ""));
        showUpdateInfo(currentUpdateIndex, true);
        this.runCopyFilesScript();
        ableStartupDownload = true;

        if (updateQueues.size() <= 0) {
            btnUpdate.setVisible(false);
            btnStartup.setVisible(true);
            lblState.setText(getLangTxt("010"));
            saveUpdateProgress();
        }
    }

    @Override
    public void handleUpdateDownloading(JUpdateManager sender, String name, long current, long total) {
        if (name != null && name.endsWith("%UFile")) {
            int indexx = Integer.parseInt(name.replace("%UFile", ""));
            if (current >= total) {
                progress.setValue(indexx);
            }
        }
    }

    private void loadConfig() {
        try {
            JUpdateManager.manager.loadConfig();
            this.setTitle(getLangTxt("002") + JUpdateManager.manager.getConfigObj().getSoftName());
            lblState.setText("");
            clearLogs();
            progress.setValue(0);
            btnStartup.setText(getLangTxt("003"));
            btnExit.setText(getLangTxt("004"));
            btnUpdate.setText(getLangTxt("013"));
            btnUpdate.setEnabled(false);
            btnStartup.setVisible(false);
            JUpdateManager.manager.setUpdateDownloadEvent(this);
            JUpdateManager.manager.clearDownloadBuffers();
            needUpdateList.clear();
            JUpdateManager.manager.searchUpdate();
        } catch (Exception ex) {
            javax.swing.JOptionPane.showMessageDialog(null, getLangTxt("001"));
            System.exit(0);
        }
    }

    public void saveUpdateProgress()
    {
        String configPaths = JUpdateManager.manager.getConfigPath();
        if (configPaths.startsWith("/home"))
        {
            SysConfig scc = JUpdateManager.manager.getConfigObj();
            scc.setNowUpdateIndex(currentUpdateObj.getUpdateIndex());
            try {
                SysConfig.save(scc, configPaths);
            } catch (Exception ex) {
                Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }else
        {
            SysConfig scc = JUpdateManager.manager.getConfigObj();
            scc.setNowUpdateIndex(currentUpdateObj.getUpdateIndex());
            try {
                SysConfig.save(scc, JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/UpdateConfig.xml");
                ArrayList<String> ttt = new ArrayList<String>();
                ttt.add("cp " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/UpdateConfig.xml" + " " + configPaths);
                JAppToolKit.JDataHelper.writeAllLines(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyConfigXmlFile.sh", ttt);
                JAppToolKit.JRunHelper.runSysCmd("chmod +x " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyConfigXmlFile.sh");
                JSudoTool.runSudoScript(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyConfigXmlFile.sh");
            } catch (Exception ex) {
                Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    @Override
    public void run() {
        while (updateQueues.size() > 0) {
            if (ableStartupDownload) {
                currentUpdateObj = updateQueues.poll();
                if (currentUpdateObj.getUpdateFiles() != null && currentUpdateObj.getUpdateFiles().length > 0) {
                    ableStartupDownload = false;
                    currentUpdateIndex++;
                    showUpdateInfo(currentUpdateIndex, false);
                    progress.setValue(0);
                    progress.setMaximum(currentUpdateObj.getUpdateFiles().length);
                    try {
                        DownloaderManager.manager.stopAllDownloader();
                        JUpdateManager.manager.downloadUpdateEntry(currentUpdateObj);
                    } catch (Exception ex) {
                        Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void runCopyFilesScript() {
        ArrayList<String> rootScripts = new ArrayList<String>();
        ArrayList<String> homeScripts = new ArrayList<String>();

        ArrayList<UpdateFileEntry> list = JUpdateManager.manager.getUpdateFileCopyList();
        String destDir = "";
        String dirCmd = "";
        for (UpdateFileEntry ufe : list) {
            if (ufe.getDest().startsWith("/%HOME%")) {
                destDir = ufe.getDest().replace("/%HOME%", JAppToolKit.JRunHelper.getUserHomeDirPath());
                dirCmd = "mkdir --parents " + new File(destDir).getParent();
                if (!homeScripts.contains(dirCmd)) {
                    //if (!new File(new File(destDir).getParent()).exists()) {
                    homeScripts.add(dirCmd);
                    //}
                }
                homeScripts.add("cp " + ufe.getSource() + " " + destDir);
            } else if (ufe.getDest().startsWith("/%DESKTOP%")) {
                destDir = ufe.getDest().replace("/%DESKTOP%", getDesktopDir());
                dirCmd = "mkdir --parents " + new File(destDir).getParent();
                if (!homeScripts.contains(dirCmd)) {
                    //if (!new File(new File(destDir).getParent()).exists()) {
                    homeScripts.add(dirCmd);
                    //}
                }
                homeScripts.add("cp " + ufe.getSource() + " " + destDir);
            } else if (ufe.getDest().startsWith("/%APPDIR%")) {
                if (JUpdateManager.manager.getConfigObj().getSoftwareWorkspace().startsWith("/home")) {
                    destDir = ufe.getDest().replace("/%APPDIR%", JUpdateManager.manager.getConfigObj().getSoftwareWorkspace());
                    dirCmd = "mkdir --parents " + new File(destDir).getParent();
                    if (!homeScripts.contains(dirCmd)) {
                        //if (!new File(new File(destDir).getParent()).exists()) {
                        homeScripts.add(dirCmd);
                        //}
                    }
                    homeScripts.add("cp " + ufe.getSource() + " " + destDir);
                } else {
                    destDir = ufe.getDest().replace("/%APPDIR%", JUpdateManager.manager.getConfigObj().getSoftwareWorkspace());
                    dirCmd = "mkdir --parents " + new File(destDir).getParent();
                    if (!rootScripts.contains(dirCmd)) {
                        //if (!new File(new File(destDir).getParent()).exists()) {
                        rootScripts.add(dirCmd);
                        //}
                    }
                    rootScripts.add("cp " + ufe.getSource() + " " + destDir);
                }
            } else {
                destDir = ufe.getDest();
                dirCmd = "mkdir --parents " + new File(destDir).getParent();
                if (!rootScripts.contains(dirCmd)) {
                    //if (!new File(new File(destDir).getParent()).exists()) {
                    rootScripts.add(dirCmd);
                    //}
                }
                rootScripts.add("cp " + ufe.getSource() + " " + destDir);
            }
        }

        try 
        {
            if (new File(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToRoot.sh").exists())
            {
                JAppToolKit.JRunHelper.runSysCmd("rm -rf " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToRoot.sh");
            }
            
            if (new File(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToHome.sh").exists())
            {
                JAppToolKit.JRunHelper.runSysCmd("rm -rf " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToHome.sh");
            }
            
            JAppToolKit.JDataHelper.writeAllLines(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToRoot.sh", rootScripts);
            JAppToolKit.JDataHelper.writeAllLines(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToHome.sh", homeScripts);

            JAppToolKit.JRunHelper.runSysCmd("chmod +x " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToRoot.sh");
            JAppToolKit.JRunHelper.runSysCmd("chmod +x " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToHome.sh");

            if (rootScripts.size() > 0) {
                JSudoTool.runSudoScript(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToRoot.sh");
            }

            JAppToolKit.JRunHelper.runSysCmd(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyUpdateFilesToHome.sh");

            JAppToolKit.JRunHelper.runSysCmd("chmod +x " + currentUpdateObj.getUpdateScriptPath());
            JAppToolKit.JRunHelper.runSysCmd(currentUpdateObj.getUpdateScriptPath());
        } catch (Exception ex) {
            Logger.getLogger(UpdateUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}